<?php
namespace zake\foundation\local;

/**
 * Class BaseDir
 * @package Fsc\File\Dir
 */
class Dir extends Local
{

    /**
     * 创建 Dir
     * @param $localPath
     * @return File|static
     * @author liu.bin 2020-05-07 10:15
     */
    public static function create($localPath)
    {
        return new static($localPath);
    }


    /**
     * 不存在则创建本地文件
     * @param string $localPath
     * @return File|static
     * @author liu.bin 2020-05-07 10:19
     */
    public static function createOrNew($localPath)
    {
        $dir = new static($localPath);
        if(!$dir->exists()){
            $dir->mkDir();
        }
        return $dir;
    }


    /**
     * Dir constructor.
     * @param string $dirName
     */
    public function __construct(string $dirName)
    {
        parent::__construct($dirName);
    }



    /**
     * 生成目录
     * @return bool
     *
     * @author liu.bin 2019-07-09 17:43
     */
    public function mkDir($mode=0755,$recursive=true)
    {
        if($this->isFile()){
            return false;
        }
        if(file_exists($this->getLocalPath())){
            return true;
        }
        if(mkdir($this->getLocalPath(),$mode,$recursive)){
            chmod($this->getLocalPath(),$mode);
            return true;
        }
        return false;
    }



    /**
     * 目录是否有子目录或文件
     *
     * @author liu.bin 2019-07-13 11:21
     */
    public function isEmpty($defaultFilter=true)
    {
        if(!$this->exists()){
            return true;
        }
        $scanList       = scandir($this->getLocalPath());
        $filterFileList = $defaultFilter ? array_merge($this->mustFileList,$this->filterFileList) : $this->mustFileList;
        $diff           = array_diff($scanList,$filterFileList);
        return empty($diff) ? true : false;
    }



    /**
     * 清空当前目录
     * 如果有子目录，则递归删除
     *
     * @author liu.bin 2019-07-13 11:10
     */
    public function empty()
    {
        if($this->isFile()){
            return false;
        }
        return $this->_emptyChild($this);
    }



    /**
     * 清空当前目录
     *
     * @return bool
     * @author liu.bin 2019-07-16 09:57
     */
    private function _emptyChild(Dir $file)
    {
        /**
         * @var Local $item
         */
        $list = $file->fileList(null,false);
        if(empty($list)){
            return true;
        }
        //
        foreach ($list as $item){
            if($item->isFile()){
                if(!@unlink((string)$item)){
                    return false;
                }
                continue;
            }
            if(!$this->_emptyChild($item)){
                return false;
            }
            if(!@rmdir((string)$item)){
                return false;
            }
        }
        return true;
    }





    /**
     * 文件列表
     * @param \Closure|null $filter
     * @$defaultFilter 是否需要过滤
     *
     * @return array|bool|mixed
     *
     * @author liu.bin 2019-07-10 10:02
     */
    public function fileList(\Closure $filter=null,$defaultFilter=true)
    {
        $scanList   = scandir($this->getLocalPath());
        $list       = [];
        foreach ($scanList as $fileName){
            if(in_array($fileName,$this->mustFileList)){
                continue;
            }
            if($defaultFilter && in_array($fileName,$this->filterFileList)){
                continue;
            }
            $fullName = rtrim($this->getLocalPath(),DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR . $fileName;
            // 默认过滤的文件和目录
            if(is_null($filter)){
                array_push($list,new File($fullName));
            }else{
                if($file = $filter($fullName)){
                    array_push($list,$file);
                }
            }
        }
        return $list;
    }




    /**
     * 所有文件列表 | 递归
     * @param \Closure|null $filter
     * @param bool $defaultFilter
     * @return array
     *
     * @author liu.bin 2019-07-16 13:58
     */
    public function allFileList(\Closure $filter=null,$defaultFilter=true)
    {
        $treeFileList = $this->_allFileList($this,$filter,$defaultFilter);
        return $treeFileList;
    }

    /**
     * 所有文件列表 | 递归
     * @param Local $masterFile
     * @param \Closure|null $filter
     * @param bool $defaultFilter
     * @return array
     *
     * @author liu.bin 2019-07-16 13:57
     */
    private function _allFileList(Dir $masterFile,\Closure $filter=null,$defaultFilter=true)
    {
        /**
         * @var Local $file
         */

        // 是否为空
        if($masterFile->isEmpty($defaultFilter)){
            return $masterFile->toMap();
        }

        $dummy = [];
        // 查询所有的文件
        $fileList = $masterFile->fileList($filter,$defaultFilter);
        foreach ($fileList as $file){
            if($file->isDirectory()){
                $fileInfo = $file->toMap();
                $fileInfo['child']  = $this->_allFileList($file,$filter,$defaultFilter);
                array_push($dummy,$fileInfo);
            }else{
                array_push($dummy,$file->toMap());
            }
        }
        return $dummy;
    }


    /**
     * 浏览目录 | 非递归
     * @return array|bool|mixed
     *
     * @author liu.bin 2020-05-07 09:30
     */
    public function scanDirs()
    {
        $list = $this->fileList(function ($fileName){
            if(is_dir($fileName)){
                return new self($fileName);
            }else{
                return null;
            }
        });
        return $list;
    }

    // 浏览文件 | 非递归
    public function scanFiles()
    {
        $list = $this->fileList(function ($fileName){
            if(is_file($fileName)){
                return new self($fileName);
            }else{
                return null;
            }
        });
        return $list;
    }



    function toMap()
    {
        return ['name'=> 'undefined'];
    }
}
